#! /gcm/jglascoe/bin/python

import sys, bsddb, string, stationstring

BAD_YEAR = 9999
BAD = None

TS_CHANGES_NAME = "Ts.strange.RSU.list.IN"

def get_new_data(new_begin, new_years, old_begin, old_years, old_data,
                 year1, year2):
    assert new_begin >= old_begin
    assert new_begin + new_years <= old_begin + old_years

    new_data = [None] * 12
    for m in range(12):
        new_monthly = []
        old_monthly = old_data[m]
        for n in range(new_years):
            year = n + new_begin
            if year1 <= year <= year2:
                datum = BAD
            else:
                datum = old_monthly[year - old_begin]
            new_monthly.append(datum)
        new_data[m] = new_monthly
    return new_data

def remove_middle(dict, data, years, begin, year1, year2):
    end = begin + years - 1
    if year1 <= begin:
        new_begin = year2 + 1
    else:
        new_begin = begin
    assert end >= year2
    new_end = end
    new_years = new_end - new_begin + 1

    new_data = get_new_data(new_begin, new_years, begin, years, data,
                            year1, year2)
    new_dict = dict.copy()
    new_dict['begin'] = new_begin

    return stationstring.serialize(new_dict, new_data)

def implement_changes(changes_dict, old_bdb, new_bdb):
    new_ids = []
    for id, el in changes_dict.items():
        s = None
        for a, x, y in el:
            if x == 0 and y == BAD_YEAR:
                continue
            if s is None:
                s = old_bdb[id]
            st = stationstring.new(s)
            dict = st.dict()
            data, years = st.data_years()
            begin = dict['begin']
            if a == "month":
                year = x
                month = y
                data[month - 1][year - begin] = BAD
                new_s = stationstring.serialize(dict, data)
            else:
                assert a == "period"
                new_s = remove_middle(dict, data, years, begin, x, y)
            s = new_s
        if s is not None:
            new_bdb[id] = s
            new_ids.append(id)

    old_ids = string.split(old_bdb['IDS'])
    for id in old_ids:
        if changes_dict.has_key(id):
            continue
        new_bdb[id] = old_bdb[id]
        new_ids.append(id)

    new_ids.sort()
    new_bdb['IDS'] = string.join(new_ids, ' ')
    new_bdb['IBAD'] = old_bdb['IBAD']

def get_changes_dict():
    dict = {}

    f = open(TS_CHANGES_NAME, 'r')
    print "reading", TS_CHANGES_NAME

    for line in f.readlines():
        split_line = string.split(line)
        id = split_line[0]
        try:
            year1, year2 = map(string.atoi, string.split(split_line[-1], "-"))
            val = ("period", year1, year2)
        except ValueError:
            year, month = map(string.atoi, string.split(split_line[-1], "/"))
            val = ("month", year, month)
        try:
            dict[id].append(val)
        except KeyError:
            dict[id] = [val]
    return dict

def main():
    changes_dict = get_changes_dict()

    in_name = sys.argv[1]
    OLD_BDB_NAME = in_name + ".bdb"
    NEW_BDB_NAME = in_name + ".strange.bdb"
    old_bdb = bsddb.hashopen(OLD_BDB_NAME, 'r')
    print "reading", OLD_BDB_NAME

    global BAD
    BAD = string.atoi(old_bdb["IBAD"]) / 10.0

    new_bdb = bsddb.hashopen(NEW_BDB_NAME, 'nc')
    print "writing", NEW_BDB_NAME

    implement_changes(changes_dict, old_bdb, new_bdb)

if __name__ == '__main__':
    main()

